if(!wfi) {var wfi = {};}


/**
 * @class wfi.CountEngine
 * Manages the 1 second interval to compute the count string
 * Delegates to whatever appender(s) is(are) defined to display the count and title
 * @param {String} jsdateStr The jsdate string that is used for the countdown/up. Must be like MM/DD/YYYY HH:MM:SS
 * @param {String} title The optional title to be displayed
 * @param {Boolean} isUp Whether it's a countup or not (a countdown)
 */
wfi.CountEngine = function(jsdateStr, title, isUp) {
	this._interval = null;
	this._ms = new Date(jsdateStr).getTime();
	this._isUp = isUp;
	this._title = title;
	this._appenders = {};
};
wfi.CountEngine.prototype = {
	/**
	 * Start the interval
	 */
	start: function() {
		var that = this;
		this._interval = setInterval(function(){
			var toBeDisplayed = {
				title: that._title,
				isUp: that._isUp,
				isOverOrNotStarted: false,
				count: ""
			};
			
			if(that._isUp) {
				var difference = new Date().getTime() - that._ms;
			} else {
				var difference = that._ms - new Date().getTime();
			}

			if(difference < 0) {
				toBeDisplayed.isOverOrNotStarted = true;
			} else {
				var daysDifference = Math.floor(difference/1000/60/60/24);
				difference = difference - daysDifference*1000*60*60*24;

				var hoursDifference = Math.floor(difference/1000/60/60);
				difference = difference - hoursDifference*1000*60*60;

				var minutesDifference = Math.floor(difference/1000/60);
				difference = difference - minutesDifference*1000*60;

				var secondsDifference = Math.floor(difference/1000);

				var string = '';

				if (daysDifference > 0) {
					string += daysDifference + ' day';
					if (daysDifference > 1) string +='s';
					string += ', ';
				}

				if((hoursDifference+"").length == 1)	hoursDifference = "0" + hoursDifference;
				if((minutesDifference+"").length == 1)	minutesDifference = "0" + minutesDifference;
				if((secondsDifference+"").length == 1)	secondsDifference = "0" + secondsDifference;

				string += hoursDifference + ':';
				string += minutesDifference + ':';
				string += secondsDifference;

				toBeDisplayed.count = string;
			}
			
			for(var i in that._appenders) {
				if(that._appenders[i].display) {
					that._appenders[i].display(toBeDisplayed);
				}
			}
		}, 1000);
	},
	
	/**
	 * Stop the interval. This will have the effect of not calling the appender(s) anymore
	 */
	stop: function() {
		clearInterval(this._interval);
	},
	
	/**
	 * Add an appender to this countEngine. Any appender must implement the display(obj) method
	 * @param {String} name The name to register the appender under
	 * @param {wfi.AppenderInterface} appender The implemention of the appender
	 */
	addAppender: function(name, appender) {
		if(!this._appenders[name]) {
			this._appenders[name] = appender;
		}
	},
	
	/**
	 * Remove an appender by its name
	 * @param {String} name
	 */
	removeAppender: function(name) {
		if(this._appenders[name]) {
			delete this._appenders[name];
		}
	}
};


/**
 * Default H1/H2 based appender implementation.
 * Will simply target every H1 and H2 tags and apply the count and title respectively to them.
 * If the countdown is over, it will fill the H1 with "countdown is over", if it's a countup and it hasn't started, it will fill it with "countdown hasn't started yet"
 */
wfi.GlobalH1H2Appender = function() {};
wfi.GlobalH1H2Appender.prototype = {
	/**
	 * Display a count in this appender. Called by the countEngine.
	 * @param {Object} obj An object containing properties count, title, isUp and isOverOrNotStarted
	 */
	display: function(obj) {
		$("h2").html(obj.title);
		if(obj.isOverOrNotStarted) {
			if(obj.isUp) {
				$("h1").html("Countup hasn't started yet!");
			} else {
				$("h1").html("Countdown is over!");
			}
		} else {
			$("h1").html(obj.count);
		}
	}
};